﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using web_uchet.Models;
using System.Reflection;
using web_uchet.Security;

namespace web_uchet.Reports.OLAP
{
    public class ПоказателиProvider
    {
        public ПоказателиProvider(OLAPFilters Filter, ProgramContext SecurityContext)
        {
            this.Filter = Filter;
            this._Context = new ModelWebUchetCon(ModelWebUchetCon.SingleToneConnection);
            this._SecurityContext = SecurityContext;
            this.Filter = Filter;
        }
        private ModelWebUchetCon _Context;
        private ProgramContext _SecurityContext;
        public OLAPFilters Filter { get; set; }
        public IQueryable<Заказ> Заказы 
        {
            get 
            {
                var Query = this._Context.Заказы.Include("Валюта").Include("Клиент").Include("Исполнитель").Include("Менеджер")
                    .Include("Менеджер.ASPNetUser").Include("Исполнитель.ASPNetUser").Include("Компания")
                    .Include("Менеджер.Место_Работы").Include("Исполнитель.Место_Работы")
                    .Where(e => e.Компания.ИД_Компании == this._SecurityContext.CompanyID);
                ParameterExpression P1=Expression.Parameter(typeof(Заказ), "P1");
                Expression predicateBody = Expression.Constant(true, typeof(bool));
                if (this.Filter.DateStart.HasValue)
                    predicateBody = Expression.And(predicateBody,
                        Expression.GreaterThanOrEqual(Expression.Property(P1, typeof(Заказ).GetProperty("Дата_Поступления", typeof(DateTime?))), 
                        Expression.Constant(this.Filter.DateStart.Value,typeof(DateTime?))));

                if (this.Filter.DateEnd.HasValue)
                    predicateBody = Expression.And(predicateBody,
                        Expression.LessThanOrEqual(Expression.Property(P1, typeof(Заказ).GetProperty("Дата_Выполнения", typeof(DateTime?))),
                        Expression.Constant(this.Filter.DateEnd.Value, typeof(DateTime?))));

                if (this.Filter.ИД_Клиента.HasValue)
                    predicateBody = Expression.And(predicateBody,
                        Expression.Equal(Expression.Property(Expression.Property(P1, "Клиент"),"ИД_Клиент"),
                        Expression.Constant(this.Filter.ИД_Клиента.Value)));

                if (this.Filter.ИД_Сотрудника.HasValue)
                    predicateBody = Expression.And(predicateBody,
                        Expression.Or(
                        Expression.Equal(
                        Expression.Property(Expression.Property(P1, "Менеджер"),"ИД_Пользователя"),
                        Expression.Constant(this.Filter.ИД_Сотрудника.Value)),
                        Expression.Equal(
                        Expression.Property(Expression.Property(P1, "Исполнитель"),"ИД_Пользователя"),
                        Expression.Constant(this.Filter.ИД_Сотрудника.Value))
                        ));

                if (this.Filter.ИД_РабочееМесто.HasValue)
                    predicateBody = Expression.And(predicateBody,
                        Expression.Or(
                        Expression.Equal(
                        Expression.Property(
                        Expression.Property(Expression.Property(P1, "Менеджер"),"Место_Работы")
                        ,"ИД_Места_Работы"),
                        Expression.Constant(this.Filter.ИД_РабочееМесто.Value)),
                        Expression.Equal(
                        Expression.Property(
                        Expression.Property(Expression.Property(P1, "Исполнитель"), "Место_Работы")
                        , "ИД_Места_Работы"),
                        Expression.Constant(this.Filter.ИД_РабочееМесто.Value))
                        ));

                //Оставшаяся фильтрация идет по агрегированным показателям, а не по измерениям

                var Filter = Expression.Lambda<Func<Заказ, bool>>(predicateBody, new ParameterExpression[] { P1 });               
                return Query.Where(Filter);
            }
        }
    }
}
